package com.ruoyi.edh.service.impl;

import com.egzosn.pay.ali.bean.AliTransactionType;
import com.egzosn.pay.common.bean.PayOrder;
import com.egzosn.pay.wx.bean.WxTransactionType;
import com.github.wxpay.sdk.WXPay;
import com.ruoyi.common.constant.WXPayConstants;
import com.ruoyi.common.exception.CustomException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.ip.IpUtils;
import com.ruoyi.common.utils.uuid.UUID;
import com.ruoyi.common.utils.wxpay.WXPayUtil;
import com.ruoyi.edh.config.WxPayConfig;
import com.ruoyi.edh.domain.EdhMasterOrder;
import com.ruoyi.edh.domain.params.WxpayParam;
import com.ruoyi.edh.mapper.EdhMasterOrderMapper;
import com.ruoyi.edh.service.IEdhMasterOrderWxPayService;
import lombok.extern.log4j.Log4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.ruoyi.common.utils.ServletUtils.getRequest;

@Service
@Log4j
public class EdhMasterOrderWxPayServiceImpl implements IEdhMasterOrderWxPayService {

    @Resource(name = "wxPay")
    private WXPay wxPay;

    @Autowired
    private WxPayConfig wxPayConfig;
    //主订单
    @Autowired
    private EdhMasterOrderMapper edhMasterOrderMapper;

    private final String NOTIFYURL = "http://easybuy.pfk2020.com:9092/edh/wx/wxPayOrder";

    private final String NOTIFYURL_MINI = "https://easybuy.yidingh.com:9093/edh/wx/wxPayOrder";

    @Override
    @Transactional(rollbackFor = Exception.class)
    public PayOrder masterOrderAliPay(String masterOrderNo) {
        PayOrder order = new PayOrder("易订货商品购买", masterOrderNo, getSumPrice(masterOrderNo), masterOrderNo, AliTransactionType.PAGE);
        //App支付
        order.setTransactionType(WxTransactionType.APP);
        return order;
    }

    @Override
    public Map<String, String> masterOrderWxPay(String masterOrderNo) {
        //根据微信支付api来设置
        Map<String, String> data = new HashMap<>();
        //金额转成分单位
        String totalFee = getSumPrice(masterOrderNo).multiply(new BigDecimal(100)).toBigInteger().toString();
        try {
            data.put("appid", wxPayConfig.getAppID());
            //商户号
            data.put("mch_id", wxPayConfig.getMchID());
            //支付场景 APP 微信app支付 JSAPI 公众号支付  NATIVE 扫码支付
            data.put("trade_type", "APP");
            //回调地址
            data.put("notify_url", NOTIFYURL);
            //终端ip
            data.put("spbill_create_ip", IpUtils.getIpAddr(getRequest()));
            //订单总金额
            data.put("total_fee", totalFee);
            //默认人民币
            data.put("fee_type", "CNY");
            //交易号
            data.put("out_trade_no", masterOrderNo);
            data.put("body", "易订货商品购买");
            data.put("attach", masterOrderNo);
            // 随机字符串小于32位
            data.put("nonce_str", UUID.randomUUID().toString());
            //签名
            String s = WXPayUtil.generateSignature(data, wxPayConfig.getKey());
            data.put("sign", s);
            Map<String, String> respData = new HashMap<String, String>();
            // wxPay.unifiedOrder 这个方法中调用微信统一下单接口
            respData = wxPay.unifiedOrder(data);
            String returnCode = respData.get("return_code");
            String returnMsg = respData.get("return_msg");
            if (WXPayConstants.FAIL.equals(returnCode)) {
                throw new CustomException(returnMsg);
            }
            if (WXPayConstants.SUCCESS.equals(returnCode)) {
                //返回给APP端的参数，APP端再调起支付接口
                Map<String, String> repData = new HashMap<>();
                repData.put("appid", wxPayConfig.getAppID());
                repData.put("partnerid", respData.get("mch_id"));
                repData.put("prepayid", respData.get("prepay_id"));
                repData.put("package", "Sign=WXPay");
                //repData.put("signType", "MD5");
                repData.put("noncestr", respData.get("nonce_str"));
                repData.put("timestamp", String.valueOf(System.currentTimeMillis() / 1000));
                System.out.println("repData:" + repData.toString());
                //签名
                String sign = WXPayUtil.generateSignature(repData, wxPayConfig.getKey());
                respData.put("sign", sign);
                respData.put("timestamp", repData.get("timestamp"));
                respData.put("package", repData.get("package"));
                System.out.println("参数:" + respData.toString());
                return respData;
            }
        } catch (Exception e) {
            throw new CustomException(e.getMessage());
        }
        return null;
    }

    /**
     * 小程序支付
     *
     * @param wxpayParam
     * @return
     * @author HuAnze
     * @date 2021/2/22
     */
    @Override
    public Map<String, String> miniProgramPay(WxpayParam wxpayParam) {
        //根据微信支付api来设置
        Map<String, String> data = new HashMap<>(16);

        String appId = wxPayConfig.getAppID();
        // 金额转成分单位
        String totalFee = getSumPrice(wxpayParam.getNo()).multiply(new BigDecimal(100)).toBigInteger().toString();

        // 随机数字字符串
        String outTradeNo = wxpayParam.getNo();
        try {
            data.put("appid", appId);
            //商户号
            data.put("mch_id", wxPayConfig.getMchID());
            //支付场景 APP 微信app支付 JSAPI 公众号支付  NATIVE 扫码支付
            data.put("trade_type", "JSAPI");
            //回调地址
            data.put("notify_url", NOTIFYURL_MINI);
            //终端ip
            data.put("spbill_create_ip", IpUtils.getIpAddr(getRequest()));
            //订单总金额
            data.put("total_fee", totalFee);
            //默认人民币
            data.put("fee_type", "CNY");
            //交易号
            data.put("out_trade_no", outTradeNo);
            //微信openid
            data.put("openid", wxpayParam.getOpenId());
            data.put("body", "易订货商品购买");
            //附加数据，在查询API和支付通知中原样返回，可作为自定义参数使用
            data.put("attach", wxpayParam.getNo());
            // 随机字符串小于32位
            data.put("nonce_str", UUID.randomUUID().toString());
            //签名
            String s = WXPayUtil.generateSignature(data, wxPayConfig.getKey());
            data.put("sign", s);
            log.info(data.toString());

            //wxPay.unifiedOrder 这个方法中调用微信统一下单接口
            Map<String, String> respData = wxPay.unifiedOrder(data);

            log.info(respData.toString());
            if (WXPayConstants.SUCCESS.equals(respData.get("return_code"))) {
                //返回给APP端的参数，APP端再调起支付接口
                Map<String, String> repData = new HashMap<>();
                repData.put("appId", appId);
                repData.put("package", "prepay_id=" + respData.get("prepay_id"));
                repData.put("signType", "MD5");
                repData.put("nonceStr", respData.get("nonce_str"));
                repData.put("timeStamp", String.valueOf(System.currentTimeMillis() / 1000));
                //签名
                String sign = WXPayUtil.generateSignature(repData, wxPayConfig.getKey());
                respData.put("sign", sign);
                respData.put("timestamp", repData.get("timeStamp"));
                respData.put("package", repData.get("package"));
                return respData;
            }
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        return null;
    }

    /**
     * 计算商品价格
     */
    private BigDecimal getSumPrice(String masterOrderNo) {
        EdhMasterOrder edhMasterOrder = new EdhMasterOrder();
        edhMasterOrder.setMasterOrderNo(masterOrderNo);
        List<EdhMasterOrder> edhMasterOrders = edhMasterOrderMapper.selectEdhMasterOrderList(edhMasterOrder);
        if (StringUtils.isNull(edhMasterOrders) || edhMasterOrders.size() == 0) {
            throw new CustomException("订单不存在");
        }
        EdhMasterOrder edhMasterOrder1 = edhMasterOrders.get(0);
        //获取商品实付总价
        BigDecimal actualAmount = edhMasterOrder1.getActualAmount();
        //获取运费价格
        BigDecimal shipping = edhMasterOrder1.getShipping();
        //算出应付价格
        return actualAmount.add(shipping);
    }

}
